// <copyright file="TabView.cs" company="YUIAsp.Net">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>raul popescu</author>
// <email>dev@yuiasp.net</email>
// <date>2009-01-30</date>
// <summary>YUIAsp.Net File</summary>

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Web.UI;
using YUIAspNet.Common;

#region Embedded resources definitions
[assembly: WebResource("YUIAspNet.TabView.TabView.js", "text/javascript")]

[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.TabView.sprite.png", "image/png")]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.TabView.tabview.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.TabView.tabview-skin.css", "text/css", PerformSubstitution = true)]
#endregion

namespace YUIAspNet
{
    /// <summary>
    /// TabView control.
    /// </summary>
    [ToolboxItem(true)]
    [System.Drawing.ToolboxBitmap(typeof(TabView), "TabView.TabView.ico")]
    public class TabView : YUIScriptBaseControl, INamingContainer, IPostBackDataHandler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TabView"/> class.
        /// </summary>
        public TabView() : base("div")
        {
            PreRender += TabView_PreRender;
        }

        void TabView_PreRender(object sender, EventArgs e)
        {
            if (Page != null)
            {
                Page.RegisterRequiresPostBack(this);
                Page.ClientScript.RegisterHiddenField(GetActiveTabName(), SelectedTabIndex.ToString(CultureInfo.InvariantCulture));
            }
        }

        private string GetActiveTabName()
        {
            return string.Concat(ClientID, ClientIDSeparator, "tabState");
        }

        /// <summary>
        /// Registers the style sheets for the current control.
        /// Must be overriden in the parent control to add any css file reference.
        /// </summary>
        protected override void RegisterStyleSheets()
        {
            RegisterEmbeddedStylesheet("TabView", "tabview.css");
            RegisterEmbeddedStylesheet("TabView", "tabview-skin.css");
        }

        /// <summary>
        /// Register the values to send to the client control for initialization.
        /// </summary>
        protected override void RegisterClientInitialization()
        {
            AddProperty("Orientation", Orientation.ToString().ToLowerInvariant());
            AddProperty("AutoPostback", AutoPostback);
            AddProperty("ActiveTabControlID", GetActiveTabName());

            if (!string.IsNullOrEmpty(OnClientAfterTabChange))
                AddEvent("onAfterChange", OnClientAfterTabChange);

            if (!string.IsNullOrEmpty(OnClientBeforeTabChange))
                AddEvent("onBeforeChange", OnClientBeforeTabChange);

            List<TabItemClient> tabClientList = new List<TabItemClient>();
            TabItemClient tabClient;

            foreach (TabItem item in Tabs)
            {
                if (!item.Visible)
                    continue;

                tabClient = new TabItemClient();
                tabClient.ID = item.ClientID;
                tabClient.Text = item.Text;
                tabClient.Active = item.Active;
                tabClient.Enabled = item.Enabled;
                tabClientList.Add(tabClient);
            }

            AddProperty("Tabs", tabClientList);
        }

        /// <summary>
        /// Registers any additional scripts to include for this control.
        /// </summary>
        protected override void RegisterScriptReferences()
        {
            AddScriptReference(new ScriptReference("YUIAspNet.TabView.TabView.js", GetType().Assembly.FullName));
        }

        #region Public properties
        /// <summary>
        /// Gets or sets the index of the selected tab.
        /// </summary>
        /// <value>The index of the selected tab.</value>
        public int SelectedTabIndex
        {
            get
            {
                TabItem selected = SelectedTab;
                if (selected != null) return Tabs.IndexOf(selected);

                return -1;
            }
            set
            {
                ClearTabSelection();

                if (value >= Tabs.Count) throw new ArgumentOutOfRangeException("value");

                Tabs[value].Active = true;
            }
        }

        /// <summary>
        /// Gets or sets the orientation.
        /// </summary>
        /// <value>The orientation.</value>
        public TabPosition Orientation { get; set; }

        /// <summary>
        /// Gets or sets the on client before tab change.
        /// </summary>
        /// <value>The on client before tab change.</value>
        public string OnClientBeforeTabChange { get; set; }

        /// <summary>
        /// Gets or sets the on client after tab change.
        /// </summary>
        /// <value>The on client after tab change.</value>
        public string OnClientAfterTabChange { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [auto postback].
        /// </summary>
        /// <value><c>true</c> if [auto postback]; otherwise, <c>false</c>.</value>
        public bool AutoPostback { get; set; }

        /// <summary>
        /// Gets or sets the selected tab.
        /// </summary>
        /// <value>The selected tab.</value>
        public TabItem SelectedTab
        {
            get
            {
                foreach (TabItem item in Tabs)
                {
                    if (item.Active)
                        return item;
                }
                return null;
            }
            set
            {
                ClearTabSelection();

                value.Active = true;
            }
        }

        /// <summary>
        /// Clears the tab selection.
        /// </summary>
        protected void ClearTabSelection()
        {
            foreach (TabItem item in Tabs)
            {
                item.Active = false;
            }
        }

        /// <summary>
        /// Gets or sets the tabs.
        /// </summary>
        [Category("Data"), Description("Tabs.")]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public TabItemCollection Tabs
        {
            get { return (TabItemCollection)Controls; }
        } 
        #endregion

        /// <summary>
        /// Creates a new <see cref="T:System.Web.UI.ControlCollection"/> object to hold the child controls (both literal and server) of the server control.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Web.UI.ControlCollection"/> object to contain the current server control's child server controls.
        /// </returns>
        protected override ControlCollection CreateControlCollection()
        {
            return new TabItemCollection(this);
        }

        #region IPostBackDataHandler Members

        /// <summary>
        /// When implemented by a class, processes postback data for an ASP.NET server control.
        /// </summary>
        /// <param name="postDataKey">The key identifier for the control.</param>
        /// <param name="postCollection">The collection of all incoming name values.</param>
        /// <returns>
        /// true if the server control's state changes as a result of the postback; otherwise, false.
        /// </returns>
        public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            if (postCollection[GetActiveTabName()] != null)
                SelectedTabIndex = int.Parse(postCollection[GetActiveTabName()], CultureInfo.InvariantCulture);

            return postCollection["__EVENTTARGET"] == ClientID;
        }

        /// <summary>
        /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
        /// </summary>
        public void RaisePostDataChangedEvent()
        {
            
        }

        #endregion
    }
}
